////////////////////////////////////////////////////////////////////////////////
//
//	This file is part of Woozox, see <http://code.google.com/p/woozox/>.
//
//	Copyright 2008-2009 Florian David
//
//	Woozoo is free software: you can redistribute it and/or modify
//	it under the terms of the GNU Lesser General Public License as 
//	published by the Free Software Foundation, either version 3 of 
//	the License, or (at your option) any later version.
//
//	Woozoo is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public 
//	License along with Woozoo. If not, see <http://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////////////
package org.woozoo.xhtml.core.manager.document
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import org.woozoo.xhtml.core.base.*;
	
	[Event(name="complete", type="flash.events.Event")]
	[Event(name="complete", type="flash.events.Event")]

	/**
	 * @private
	 * */
	public class DocumentManager extends EventDispatcher
	{
		public static var DOCUMENT_INDEX_NAME : String;
		public static var DOCUMENT_INDEX_URL : String;
		
		public static var CATEGORY_DEFAULT : Category;
		
		private static var __instance : DocumentManager;
		protected static var _instanciable : Boolean = false;

		private var __documents : Array = [];
		private var __documentsByName : Object = {};
		private var __categories : Array = [];
		private var __categoriesByName : Object = {};
		private var __defaultDocumentClass : Class = Document;
		private var __defaultCategoryClass : Class = Category;
		
		public function DocumentManager()
		{
			if (!_instanciable) {
				throw new Error('DocumentManager is a singleton class, call DocumentManager.getInstance() instead');
			}
		}
		
		public static function getInstance() : DocumentManager {
			if (!__instance) {
				_instanciable = true;
				__instance = new DocumentManager();
				_instanciable = false;
			}
			return __instance;
		}
		
		public function get defaultDocumentClass() : Class {
			return __defaultDocumentClass;
		}
		public function set defaultDocumentClass(value : Class) : void {
			__defaultDocumentClass = value;
		}

		public function get defaultCategoryClass() : Class {
			return __defaultCategoryClass;
		}
		public function set defaultCategoryClass(value : Class) : void {
			__defaultCategoryClass = value;
		}
		
		public function getAndCreateIfNecessaryCategoryByName(name : String) : Category {
			var c : Category = getCategoryByName(name);
			if (!c) {
				c = new defaultCategoryClass(name);
				addCategory(c);
			} 
			return c;
		}
		
		public function getCategoryByName(name : String) : Category {
			return __categoriesByName[name];
		}
		
		public function get categories() : Array {
			return __categories;
		}
		
		public function setup(indexUrl : String, indexName : String) : Document {
			DOCUMENT_INDEX_NAME = indexName;
			DOCUMENT_INDEX_URL = indexUrl;
			__documents = [];
		 	__documentsByName = {};
		 	__categoriesByName = {};
		 	CATEGORY_DEFAULT = new Category(Category.DEFAULT_CATEGORY_NAME);
			return addAndCreateDocument(DOCUMENT_INDEX_NAME, DOCUMENT_INDEX_URL)
		}
		
		public function addCategory(category : Category) : Category {
			if (!__categoriesByName[category.name]) {
				__categoriesByName[category.name] = category;
			}
			if (__categories.indexOf(category) == -1) {
				__categories.push(category);
			}
			return category;
		}
		
		
		public function addDocument(doc : Document) : Document {
			__addDocumentToIndexes(doc, doc.categories);
			return doc;
		}
		
		public function addAndCreateDocument(id : String, url : String, categories : Array = null) : Document {
			var doc : Document = new defaultDocumentClass(id, url);
			if (categories) {
				doc.categories =  categories;
			} else {
				doc.categories = [];
				doc.categories.push(CATEGORY_DEFAULT);
			}
			return addDocument(doc);
		}
		
		public function loadDocument(doc : Document) : Document {
			doc.load();
			return doc;
		}
		
		public function getDocumentByName(name : String) : Document {
			return __documentsByName[name];
		}
		
		public function getDocumentsByCategoryName(name : String) : Array {
			var category : Category = __categoriesByName[name];
			if (!category) return [];
			return category.documents;
		}
		
		public function addAndCreateDocumentsByContainer(doc : Document, container : Element, categories : Array = null) : Array {
			var list : Array = [];
			if (!categories) {
				categories = [];
				categories.push(CATEGORY_DEFAULT);
			}
			
			if (!container) return list;
			var targets : Array = container.getElementsByTagName('a');
			var len : int = targets.length;
			for (var i : int = 0; i < len; i++) {
				var target : Element = targets[i];
				var name : String = target.innerHTML;
				var url : String = target.att('href');
				list.push(addAndCreateDocument(name, url, categories));
			}
			return list;
		}
		
		public function get documentIndex() : Document {
			return getDocumentByName(DOCUMENT_INDEX_NAME);
		}
		
		private function __addDocumentToIndexes(document : Document, categories : Array) : void {
			if (__documentsByName[document.name]) return;
			
			if (!categories) {
				categories = [];
				categories.push(CATEGORY_DEFAULT);
			}
			document.categories = categories;
			__documents.push(document);
			__documentsByName[document.name] = document;
			
			var len : int = categories.length;
			for (var  i : int = 0; i < len; i++) {
				var category : Category = categories[i];
				if (!__categoriesByName[category.name]) {
					__categoriesByName[category.name] = category;
				}
				if (__categories.indexOf(category) == -1) {
					__categories.push(category);
				}
				category.addDocument(document);
			}
		}
	}
}